package com.qianfeng.android.baoman.util;

/**
 * Created by maxiaoyu on 2015/2/6.
 * User:Maxiaoyu
 * Date:2015/2/6
 * Email:731436452@qq.com
 */

import android.graphics.Bitmap;
import android.os.Build;
import android.support.v4.util.LruCache;

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * 图片缓存工具，只进行内存图片的管理，如果需要进行文件缓存的管理
 * 请调用FileCache 进行操作
 */
public class ImageCache {
    private static ImageCache ourInstance = null;

    public static ImageCache getInstance() {
        if (ourInstance == null) {
            ourInstance = new ImageCache();
        }
        return ourInstance;
    }
    //1.声明一级缓存  缓存在内存中有固定的大小，如果缓存超过这个大小限制，删掉最旧的缓存
    // 条目，添加新的内容
    /**
     * 一级缓存采用固定内存尺寸的方式存储部分内容，
     * 当空间不足时，采用LUR（Least Recently Used)算法将很少使用，很长时间没有使用的对象替换掉
     */
    private LruCache<String, Bitmap> firstCache;
    // 2. 声明第二级缓存，缓存直接采用HashMap进行存储，存储的对象是SoftReference来引用的对象，
    // HashMap 的操作，可以一直添加，当内存不足时，会直接回收，因此可以充分利用内存，尽可能多的
    //在内存中保存Bitmap实例，因为内存访问非常快
    private HashMap<String, SoftReference<Bitmap>> secondCache;

    private ImageCache() {
        //LruCache 构造方法最大尺寸这个参数代表，当前的缓存在内存中占用最大字节数
        // 谷歌建议LruCache 最大内存字节数是当前系统可用内存的1/8
        /*  long freeMemory = Runtime.getRuntime().freeMemory();//得到当前栈中可利用的内存。
      if (freeMemory > 0) {
            freeMemory = freeMemory / 8;
        } else {

        }*/
        //设置缓存去大小为5M
        long freeMemory = 5 * 1024 * 1024;  //5M
        firstCache = new LruCache<String, Bitmap>((int) freeMemory) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                int size = 0;
                //Android中判断版本号
                if (Build.VERSION.SDK_INT >= 19) {
//                    size = value.getAllocationByteCount();
                } else {
                    int rowBytes = value.getRowBytes();//一行的字节数，
                    int height = value.getHeight();
                    size = rowBytes * height;
                }
                return size;
            }
        };
        secondCache = new LinkedHashMap<String, SoftReference<Bitmap>>();
    }

    /**
     * //获取内存缓存中指定url 地址图片
     *
     * @param url
     * @return
     */
    public Bitmap getImage(String url) {
        Bitmap ret = null;
        if (url != null) {
            //先从第一级缓存查找，找到则直接返回，未找到，从第二季查找
            ret = firstCache.get(url);
            if (ret == null) {
                //第一季没有缓存，查第二级
                if (secondCache.containsKey(url)) {
                    //如果第二级有url的引用，那么查找内部的数据
                    //第二级内部数据由于是SoftReference,很可能获取出来的结果是null
                    //因为ＧＣ可以吧ＳｏｒｔＲｅｆｅｒｅｎｃｅ　对象释放
                    SoftReference<Bitmap> reference = secondCache.get(url);
                    if (reference != null) {
                        ret = reference.get();//获取引用的实际对象
                    }
                }
            }
        }
        return ret;
    }

    /**
     * 更新内存缓存
     *
     * @param url
     * @param bitmap
     */
    public void putImage(String url, Bitmap bitmap) {
        if (url != null && bitmap != null) {
            //更新第二级缓存
            secondCache.put(url, new SoftReference<Bitmap>(bitmap));
            //更新第一季缓存
            firstCache.put(url, bitmap);
        }
    }
}
